import {Injectable} from "@angular/core";
import {DataStorageUtil} from "./data-storage-util";
import {API, AppConstants, Components, MsgConstants} from "../constants/constants";
import {Http, RequestOptions, Response, Headers} from "@angular/http";
import {LogUtil} from "./log-util";
import {MsgResult} from "../models/msg-result";
import {Router} from "@angular/router";
import {Observable} from "rxjs/Observable";
import {OneDialogService} from "../widgets/one-dialog/one-dialog.service";
import {Dialog} from "../widgets/one-dialog/dialog";
/**
 * Token管理工具类
 * Created by duqunxing on 2017/8/25.
 */
@Injectable()
export class TokenUtil{
  constructor(
    private dataStorage:DataStorageUtil,
    private http:Http,
    private logUtil:LogUtil,
    private dialogService:OneDialogService,
    private router:Router

  ){}


  /**
   * 存储token
   * 存储token，refreshToken以及token过期时间
   * @param token
   * @param refreshToken
   * @param expire
   */
  setToken(token:string,refreshToken:string,expire:string){
    this.dataStorage.set(AppConstants.token,token);
    this.dataStorage.set(AppConstants.refreshToken,refreshToken);
    this.dataStorage.set(AppConstants.expire,expire);
  }

  /**
   * 获取token
   * <p>
   * 1.从存储中获取token;
   * 2.如果获取不到，就根据refreshToken请求新的token,并存储;
   * 3.如果请求新token失败，则重定向到登录页面
   * </p>
   * @returns {string}
   */
  getToken(): string {
    let token = this.dataStorage.get(AppConstants.token);
    return token;
  }

  refreshToken():Observable<string> | any{
    let refreshToken = this.dataStorage.get(AppConstants.refreshToken);
    let params = "refreshToken=" + refreshToken;
    return this.http.post(API.requestRefreshToken,params,this.getRequestOptions())
      .subscribe(
        res => this.success(res),
        error => this.error(error)
      );
  }

  getRequestOptions(){
    let headers = new Headers({'Content-Type': 'application/x-www-form-urlencoded'});
    headers.append('X-Requested-With', 'XMLHttpRequest' );
    let _defaultOptions = new RequestOptions({headers:headers});
    return _defaultOptions;
  }

  /**
   * 成功处理
   * @param res
   * @returns {any}
   */
  private success(res :Response):string | any {
    let result = res.json();
    if(this.preSuccess(result)){
      let token = result.data.token;
      let refreshToken = result.data.refreshToken;
      let expire = result.data.expire;
      //存储token
      this.setToken(token,refreshToken,expire);
      this.dialogService.push(new Dialog());
      return token;
    }else {
      this.redirect();
      return;
    }

  }

  /**
   * 失败处理
   * @param error
   * @returns {string}
   */
  private error(error: Response | any) : string | any{
    let errMsg: string;
    if (error instanceof Response) {
      const body = error.json() || '';
      const err = body.error || JSON.stringify(body);
      errMsg = `${error.status} - ${error.statusText || ''} ${err}`;
    } else {
      errMsg = error.message ? error.message : error.toString();
    }
    this.logUtil.error(errMsg);
    this.redirect();
    return errMsg;
  }
  redirect(){
    this.router.navigateByUrl(Components.authenComponent);
  }

  /**
   * 请求成功前置处理方法
   * @param result
   * @returns {boolean}
   */
  preSuccess(result:MsgResult | any) :boolean{
    if(result && result.code){
      if(result.code != MsgConstants.MSG_CODE_OK){
        let resultCode =  Number.parseInt(result.code);
        if(resultCode >= MsgConstants.MSG_CODE_AUTH_ERROR_MIN && resultCode <= MsgConstants.MSG_CODE_AUTH_ERROR_MAX){
          this.redirect();
          return false;
        }
      }
      return true;
    }
    return false;
  }

}
